﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Input;

namespace The_LarX
{
    public delegate void SetPropertyGrid(object obj);
    public class VisualScriptEditor : Component
    {
        private Camera2D Camera;
        public List<VisualScript> VisualScripts;

        public VisualScript CurrentVisualScript
        {
            get { return VisualScripts[CurrentVisualScriptIndex]; }
        }
        public int CurrentVisualScriptIndex;

        public List<RectangleOwner> Rectangles;

        public VSRBase MovingNode;

        public SetPropertyGrid SetProp;

        public RectangleOwner WaitingNode;

        public Button PlusVisualScripts;
        public Button MinusVisualScripts;

        public VisualScriptEditor(GameScreen gs)
            : base(gs)
        {
            this.Serialiable = false;
            Load();
        }

        private void Load()
        {
            Rectangles = new List<RectangleOwner>();

            Camera = new Camera2D(this.Parent);

            VisualScripts = new List<VisualScript>();

            VisualScript script = new VisualScript(Engine.GameScreens[0]);
            script.Visible = false;
            VisualScripts.Add(script);

            PlusVisualScripts = new Button(new Sprite2D(new Vector2(0, 0), "+"), this.Parent);
            PlusVisualScripts.OnTex.DrawRectangle = true;
            PlusVisualScripts.OnTex.RectangleColor = Color.LightGray;
            PlusVisualScripts.OnClick += new EventHandler(PlusVisualScripts_OnClick);

            MinusVisualScripts = new Button(new Sprite2D(new Vector2(30, 0), "-"), this.Parent);
            MinusVisualScripts.OnTex.DrawRectangle = true;
            MinusVisualScripts.OnTex.RectangleColor = Color.LightGray;
            MinusVisualScripts.OnClick += new EventHandler(MinusVisualScripts_OnClick);

            CurrentVisualScriptIndex = 0;

            Speed = 10;
        }

        void MinusVisualScripts_OnClick(object sender, EventArgs e)
        {
            CurrentVisualScriptIndex--;
            if (CurrentVisualScriptIndex < 0)
                CurrentVisualScriptIndex = VisualScripts.Count - 1;
        }

        void PlusVisualScripts_OnClick(object sender, EventArgs e)
        {
            CurrentVisualScriptIndex++;
            if (CurrentVisualScriptIndex > VisualScripts.Count - 1)
                CurrentVisualScriptIndex = 0;
        }

        public int Speed { get; set; }
        public override void Update()
        {
            base.Update();

            CurrentVisualScript.Update();
            for (int k = 0; k < CurrentVisualScript.Nodes.Count; k++)
                if (CurrentVisualScript.Nodes[k].Representation != null)
                {
                    CurrentVisualScript.Nodes[k].Representation.Camera = Camera;
                    CurrentVisualScript.Nodes[k].Representation.Update();
                }
            
            if (Engine.Input.MouseLeftClick())
            {
                int X = Engine.Input.MouseState.X + (int)Camera.Position.X;
                int Y = Engine.Input.MouseState.Y + (int)Camera.Position.Y;
                Rectangle rect = new Rectangle(X, Y, 1, 1);
                bool IntersectedAny = false;
                for (int i = 0; i < Rectangles.Count; i++)
                {
                    if (Rectangles[i].Owner.Node.Script == CurrentVisualScript)
                    {
                        if (WaitingNode == null)
                        {
                            // If the current Node is null
                            if (Rectangles[i].Rectangle.Intersects(rect))
                            {
                                IntersectedAny = true;
                                WaitingNode = Rectangles[i];
                                WaitingNode.Active = true;
                            }
                        }
                        else
                        {
                            // Not null
                            if (WaitingNode != Rectangles[i])
                            {
                                if (Rectangles[i].Rectangle.Intersects(rect))
                                {
                                    IntersectedAny = true;
                                    if (WaitingNode.Owner == Rectangles[i].Owner)
                                    {
                                        // If it's another rectangle from the same Owner,
                                        // just change the rectangles
                                        WaitingNode.Active = false;
                                        WaitingNode = Rectangles[i];
                                        WaitingNode.Active = true;
                                    }
                                    else
                                    {
                                        // Selected another node!
                                        if (Rectangles[i].AddList != null)
                                        {
                                            VisualScript_Node node = WaitingNode.Owner.Node;
                                            if (node is IVisualScriptNode_Actor &&
                                                Rectangles[i].ExpectedNode == ExpectedNode.Condition ||
                                                node is IVisualScriptNode_Condition &&
                                                Rectangles[i].ExpectedNode == ExpectedNode.Condition ||
                                                node is IVisualScriptNode_Object &&
                                                Rectangles[i].ExpectedNode == ExpectedNode.Object)
                                            {
                                                if (!Rectangles[i].AddList.Contains(WaitingNode.Owner.Node))
                                                    Rectangles[i].AddList.Add(WaitingNode.Owner.Node);
                                                WaitingNode.Active = false;
                                                WaitingNode = null;
                                            }
                                        }
                                        else
                                        {
                                            if (WaitingNode.AddList != null)
                                            {
                                                VisualScript_Node node = Rectangles[i].Owner.Node;
                                                if (node is IVisualScriptNode_Actor &&
                                                    WaitingNode.ExpectedNode == ExpectedNode.Condition ||
                                                    node is IVisualScriptNode_Condition &&
                                                    WaitingNode.ExpectedNode == ExpectedNode.Condition ||
                                                    node is IVisualScriptNode_Object &&
                                                    WaitingNode.ExpectedNode == ExpectedNode.Object)
                                                {
                                                    if (!WaitingNode.AddList.Contains(Rectangles[i].Owner.Node))
                                                        WaitingNode.AddList.Add(Rectangles[i].Owner.Node);
                                                    WaitingNode.Active = false;
                                                    WaitingNode = null;
                                                }
                                            }
                                        }
                                        /*switch (WaitingNode.ConnectionType)
                                        {
                                            case NodeConnectionType.AssignNodeToAConditional:
                                                {
                                                    //if (!Rectangles[i].Owner.Node.Conditionals.Contains(WaitingNode.Owner.Node))
                                                    //    Rectangles[i].Owner.Node.Conditionals.Add(WaitingNode.Owner.Node);
                                                    if (Rectangles[i].AddList != null)
                                                    {
                                                        if (!Rectangles[i].AddList.Contains(WaitingNode.Owner.Node))
                                                            Rectangles[i].AddList.Add(WaitingNode.Owner.Node);
                                                        WaitingNode.Active = false;
                                                        WaitingNode = null;
                                                    }
                                                }
                                                break;
                                            case NodeConnectionType.AssignConditionToNode:
                                                {
                                                    //if (!WaitingNode.Owner.Node.Conditionals.Contains(Rectangles[i].Owner.Node))
                                                    //    WaitingNode.Owner.Node.Conditionals.Add(Rectangles[i].Owner.Node);
                                                    if (WaitingNode.AddList != null)
                                                    {
                                                        if (!WaitingNode.AddList.Contains(Rectangles[i].Owner.Node))
                                                            WaitingNode.AddList.Add(Rectangles[i].Owner.Node);
                                                        WaitingNode.Active = false;
                                                        WaitingNode = null;
                                                    }
                                                }
                                                break;

                                        }*/
                                    }
                                }
                            }
                        }
                    }                    
                }
                if (!IntersectedAny)
                {
                    if (WaitingNode != null)
                    {
                        WaitingNode.Active = false;
                        WaitingNode = null;
                    }
                }
            }

            if (Engine.Input.IsKeyboardDown(Keys.Up))
            {
                Camera.Position.Y -= Speed;
            }
            if (Engine.Input.IsKeyboardDown(Keys.Down))
            {
                Camera.Position.Y += Speed;
            }
            if (Engine.Input.IsKeyboardDown(Keys.Left))
            {
                Camera.Position.X -= Speed;
            }
            if (Engine.Input.IsKeyboardDown(Keys.Right))
            {
                Camera.Position.X += Speed;
            }
            if (Engine.Input.IsKeyboardDown(Keys.OemPlus))
            {
                Camera.Position.Z += (float)Speed / 200f;
            }
            if (Engine.Input.IsKeyboardDown(Keys.OemMinus))
            {
                Camera.Position.Z -= (float)Speed / 200f;
            }
        }
        public override void Draw()
        {
            base.Draw();

            Engine.QueuedActions.AddQueuedAction(0, DrawAll);
        }
        private void DrawAll()
        {
            int X = Engine.Input.MouseState.X;
            int Y = Engine.Input.MouseState.Y;
            Engine.RenderManager.DrawRectangle(Color.Red, new Rectangle(X, Y, 20, 20), null);
            Engine.RenderManager.DrawString(Vector3Util.Format(Camera.Position, "X: ", "Y: ", "Zoom:",  5), 2,
                200, new Vector2(30), "Kootenay", Color.White, null, 0, Vector2.Zero, 0.5f, 0);
            CurrentVisualScript.Draw();
            for (int k = 0; k < CurrentVisualScript.Nodes.Count; k++)
                if (CurrentVisualScript.Nodes[k].Representation != null)
                {
                    CurrentVisualScript.Nodes[k].Representation.Draw();
                }
        }

        public event EventHandler OnRequestInformation;
        public NodeInformation LastNodeInformation;
        private VisualScript_Node LastNode;
        public void RequestInformation(VisualScript_Node Node, NodeInformation Information)
        {
            this.LastNodeInformation = Information;
            this.LastNode = Node;

            if (OnRequestInformation != null)
                OnRequestInformation(this, EventArgs.Empty);
        }

        public void ReceiveInformation(NodeInformation Information)
        {
            LastNode.ReceiveInformation(Information);
        }
    }
}
